package com.example.dw.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.example.dw.dto.*;
import com.example.dw.entity.Order;
import com.example.dw.mapper.OrderMapper;
import com.example.dw.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单服务实现类
 * @author system
 * @since 2024-01-01
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Override
    public Map<String, Object> getAllOrders(Integer userid, OrderQueryDTO queryDTO) {
        Integer page = queryDTO.getPage() != null && queryDTO.getPage() > 0 ? queryDTO.getPage() : 1;
        Integer size = queryDTO.getSize() != null && queryDTO.getSize() > 0 ? queryDTO.getSize() : 10;
        Integer offset = (page - 1) * size;

        List<Order> orders = orderMapper.getOrdersByUserPage(userid, offset, size);
        Integer total = orderMapper.getOrderCountByUser(userid);

        Map<String, Object> result = new HashMap<>();
        result.put("list", orders);
        result.put("total", total);
        result.put("page", page);
        result.put("size", size);
        result.put("pages", (total + size - 1) / size);

        return result;
    }

    @Override
    public Map<String, Object> getOrdersWeb(Integer userid, OrderQueryDTO queryDTO) {
        // Web端可能需要不同的展示格式，这里先保持一致
        return getAllOrders(userid, queryDTO);
    }

    @Override
    @Transactional
    public Map<String, Object> pay(Integer userid, OrderCreateDTO createDTO) {
        // 创建订单
        Order order = createOrder(userid, createDTO);

        // TODO: 集成支付网关
        // 这里应该调用实际的支付网关API，比如微信支付、支付宝等
        Map<String, Object> paymentResult = processPayment(order, "mobile");

        Map<String, Object> result = new HashMap<>();
        result.put("orderid", order.getOrderid());
        result.put("reqsn", order.getReqsn());
        result.put("trxamt", order.getTrxamt());
        result.put("paymentInfo", paymentResult);

        return result;
    }

    @Override
    @Transactional
    public Map<String, Object> payWeb(Integer userid, OrderCreateDTO createDTO) {
        // 创建订单
        Order order = createOrder(userid, createDTO);

        // TODO: 集成支付网关（Web端）
        Map<String, Object> paymentResult = processPayment(order, "web");

        Map<String, Object> result = new HashMap<>();
        result.put("orderid", order.getOrderid());
        result.put("reqsn", order.getReqsn());
        result.put("trxamt", order.getTrxamt());
        result.put("paymentInfo", paymentResult);

        return result;
    }

    @Override
    public Order getOrderById(Integer userid, Integer orderid) {
        Order order = orderMapper.getOrderByIdWithDetails(orderid);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 验证订单属于当前用户
        if (!order.getUserid().equals(userid)) {
            throw new RuntimeException("无权访问此订单");
        }

        return order;
    }

    @Override
    @Transactional
    public Map<String, Object> paymentNotify(PaymentNotifyDTO notifyDTO) {
        // 验证回调签名
        if (!validateNotifySign(notifyDTO)) {
            log.error("支付回调签名验证失败：{}", notifyDTO.getReqsn());
            return createNotifyResponse(false, "签名验证失败");
        }

        // 查找订单
        Order order = orderMapper.getOrderByReqsn(notifyDTO.getReqsn());
        if (order == null) {
            log.error("支付回调订单不存在：{}", notifyDTO.getReqsn());
            return createNotifyResponse(false, "订单不存在");
        }

        // 检查订单状态
        if (order.getTrxstatus() == 1) {
            log.info("订单已经支付成功：{}", notifyDTO.getReqsn());
            return createNotifyResponse(true, "订单已处理");
        }

        // 更新订单状态
        try {
            orderMapper.updateOrderPayStatus(
                notifyDTO.getReqsn(),
                notifyDTO.getTrxstatus(),
                notifyDTO.getTrxid(),
                notifyDTO.getChnltrxid(),
                notifyDTO.getFintime()
            );

            log.info("订单支付状态更新成功：{}", notifyDTO.getReqsn());
            
            // TODO: 处理支付成功后的业务逻辑
            // 比如：发送通知、更新库存、发放权限等
            if (notifyDTO.getTrxstatus() == 1) {
                handlePaymentSuccess(order);
            }

            return createNotifyResponse(true, "处理成功");
        } catch (Exception e) {
            log.error("更新订单支付状态失败：{}", notifyDTO.getReqsn(), e);
            return createNotifyResponse(false, "处理失败");
        }
    }

    @Override
    public Map<String, Object> getWCOrder(String reqsn) {
        if (StrUtil.isBlank(reqsn)) {
            throw new RuntimeException("订单号不能为空");
        }

        Order order = orderMapper.getOrderByReqsn(reqsn);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // TODO: 查询支付网关的订单状态
        Map<String, Object> wcOrderStatus = queryPaymentGatewayStatus(reqsn);

        Map<String, Object> result = new HashMap<>();
        result.put("order", order);
        result.put("paymentStatus", wcOrderStatus);

        return result;
    }

    @Override
    @Transactional
    public Map<String, Object> continuePay(Integer userid, OrderPayDTO payDTO) {
        Order order = getOrderById(userid, payDTO.getOrderid());
        
        // 检查订单状态
        if (order.getTrxstatus() == 1) {
            throw new RuntimeException("订单已支付成功");
        }
        if (order.getTrxstatus() == 2) {
            throw new RuntimeException("订单已过期");
        }

        // 检查订单是否过期
        if (isOrderExpired(order)) {
            // 更新订单为过期状态
            order.setTrxstatus(2);
            orderMapper.updateById(order);
            throw new RuntimeException("订单已过期");
        }

        // 重新发起支付
        Map<String, Object> paymentResult = processPayment(order, payDTO.getPlatform());

        Map<String, Object> result = new HashMap<>();
        result.put("orderid", order.getOrderid());
        result.put("reqsn", order.getReqsn());
        result.put("trxamt", order.getTrxamt());
        result.put("paymentInfo", paymentResult);

        return result;
    }

    @Override
    @Transactional
    public Order createOrder(Integer userid, OrderCreateDTO createDTO) {
        // 验证订单数据
        validateOrderData(createDTO);

        Order order = new Order();
        order.setUserid(userid);
        order.setOrderOfType(createDTO.getOrderOfType());
        order.setCourseid(createDTO.getCourseid());
        order.setSessionid(createDTO.getSessionid());
        order.setPriceid(createDTO.getPriceid());
        order.setTrxamt(createDTO.getTrxamt());
        order.setBody(createDTO.getBody());
        order.setNum(createDTO.getNum() != null ? createDTO.getNum() : 1);
        order.setPaytype(createDTO.getPaytype() != null ? createDTO.getPaytype() : "wxpay");
        order.setValidtime(createDTO.getValidtime() != null ? createDTO.getValidtime() : 30); // 默认30分钟
        order.setIdno(createDTO.getIdno());
        order.setTruename(createDTO.getTruename());
        order.setPhoneList(createDTO.getPhoneList());
        order.setUserFormFields(createDTO.getUserFormFields());
        order.setTicketType(createDTO.getTicketType());
        order.setRemarks(createDTO.getRemarks());

        // 生成订单号
        String reqsn = generateOrderNumber();
        order.setReqsn(reqsn);

        // 生成随机字符串
        order.setRandomstr(IdUtil.simpleUUID());

        // 设置订单状态为待支付
        order.setTrxstatus(0);
        order.setCreatedAt(LocalDateTime.now());

        // TODO: 设置支付相关参数
        order.setSigntype("MD5");
        order.setNotifyUrl("https://yourdomain.com/api/order/wcnimbiejinlaishouyangluyifaq12/78nongdaoyidibusgun8");

        orderMapper.insert(order);

        return order;
    }

    @Override
    public void processExpiredOrders() {
        try {
            int updatedCount = orderMapper.updateExpiredOrdersStatus();
            log.info("处理过期订单完成，更新数量：{}", updatedCount);
        } catch (Exception e) {
            log.error("处理过期订单失败", e);
        }
    }

    /**
     * 验证订单数据
     */
    private void validateOrderData(OrderCreateDTO createDTO) {
        if (createDTO.getOrderOfType() == 0 && createDTO.getCourseid() == null) {
            throw new RuntimeException("课程订单必须指定课程ID");
        }
        if (createDTO.getOrderOfType() == 1 && createDTO.getSessionid() == null) {
            throw new RuntimeException("活动订单必须指定活动场次ID");
        }
        if (createDTO.getTrxamt() == null || createDTO.getTrxamt().compareTo(BigDecimal.ZERO) <= 0) {
            throw new RuntimeException("订单金额必须大于0");
        }
    }

    /**
     * 生成订单号
     */
    private String generateOrderNumber() {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String random = String.valueOf((int)((Math.random() * 9 + 1) * 1000));
        return timestamp + random;
    }

    /**
     * 处理支付
     */
    private Map<String, Object> processPayment(Order order, String platform) {
        // TODO: 实际的支付网关集成
        // 这里应该调用微信支付、支付宝等支付接口
        
        Map<String, Object> result = new HashMap<>();
        result.put("payType", order.getPaytype());
        result.put("orderNo", order.getReqsn());
        result.put("amount", order.getTrxamt());
        result.put("platform", platform);
        
        // 模拟返回支付信息
        if ("wxpay".equals(order.getPaytype())) {
            result.put("prepayId", "wx_prepay_" + IdUtil.simpleUUID());
            result.put("codeUrl", "weixin://wxpay/bizpayurl?pr=" + IdUtil.simpleUUID());
        }
        
        return result;
    }

    /**
     * 验证支付回调签名
     */
    private boolean validateNotifySign(PaymentNotifyDTO notifyDTO) {
        // TODO: 实现实际的签名验证逻辑
        // 根据具体的支付网关要求进行签名验证
        return true; // 临时返回true，实际应该进行严格的签名验证
    }

    /**
     * 创建回调响应
     */
    private Map<String, Object> createNotifyResponse(boolean success, String message) {
        Map<String, Object> result = new HashMap<>();
        result.put("success", success);
        result.put("message", message);
        result.put("code", success ? "SUCCESS" : "FAIL");
        return result;
    }

    /**
     * 处理支付成功后的业务逻辑
     */
    private void handlePaymentSuccess(Order order) {
        // TODO: 实现支付成功后的业务逻辑
        // 比如：
        // 1. 发送支付成功通知
        // 2. 更新商品库存
        // 3. 给用户发放权限
        // 4. 记录支付日志等
        
        log.info("处理订单支付成功后续逻辑：{}", order.getReqsn());
    }

    /**
     * 查询支付网关状态
     */
    private Map<String, Object> queryPaymentGatewayStatus(String reqsn) {
        // TODO: 实际查询支付网关的订单状态
        Map<String, Object> result = new HashMap<>();
        result.put("orderNo", reqsn);
        result.put("status", "UNKNOWN");
        result.put("message", "需要集成具体支付网关");
        return result;
    }

    /**
     * 检查订单是否过期
     */
    private boolean isOrderExpired(Order order) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime expireTime = order.getCreatedAt().plusMinutes(order.getValidtime());
        return now.isAfter(expireTime);
    }
} 